package kotlinLearning.catherineliujj.main.start

import kotlin.math.roundToInt

/**
 * 开始  基本语法
 */
val PI = 3.14
var x = 1;

fun increase() {
    x += 1
}

val q: Int = 0
val q2: Double
    get() = 1.0
val q3: Int
    get() {
        return 1
    }


fun main() {

//    var string = "x is $x"
//    var stringAfter = "x is $x"
//    var increaseX = increase()
//    println(string.replace("is", "was") + ", but now " + stringAfter)
//
//    var s = "s is equalsTo $x"
//    increase()
//    val s2 = "${s.replace("is", "was")}, but now is $x"
//    println(s2)
//    println(max(x, x + 1))
//    println(max2(x, x + 1))
//
//    printProduct("6", "2")
//    printProduct2("6", "2")
//    val stringLength = getStringLength(1)
//    val stringLength2 = getStringLength2("2")
//    val stringLength3 = getStringLength3("3")
//    println(stringLength)
//    println(stringLength2)
//    println(stringLength3)
//
//    doFor()
//    doFor2()
//    doWhile()
//    doWhile()
//    println(describe(1))
//    println(describe("Hello"))
//    println(describe(666L))
//    println(describe("other"))
//
//    aboutRange()
//    aboutSet()

//    printLength("Incomprehensibilities")
//    printLength(1000)
//    printLength(listOf(Any()))

    val rectangle = Rectangle(5.0, 2.0)
//    rectangle.isSquare = true
    val triangle = Triangle(3.0, 4.0, 5.0)
    println("Area of rectangle is ${rectangle.calculateArea()}, its perimeter is ${rectangle.perimeter}, ${rectangle.isSquare}")
    println("Area of triangle is ${triangle.calculateArea()}, its perimeter is ${triangle.perimeter}")

}

fun printLength(obj: Any){
    println("'$obj' string length is ${getStringLength(obj)?:"...err, not a string"}")
}

fun max(a: Int, b: Int) : Int{
    if (a > b){
        return a
    } else {
        return b
    }
}
fun max2(a: Int, b: Int) = if (a > b) a else b

fun parseInt(str: String): Int? {
    return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String){
    val x = parseInt(arg1)
    val y = parseInt(arg2)

    if (x != null && y != null){
        println(x * y)
    } else {
        println("'$arg1' or '$arg2' is nt Integer")
    }
}
fun printProduct2(arg1: String, arg2: String){
    val x = parseInt(arg1)
    val y = parseInt(arg2)

    if (x == null){
        println("Wrong number format in arg1: '$arg1'")
        return
    }
    if (y == null){
        println("Wrong number format in arg2: '$arg2")
        return
    }
    println(x + y)

}

fun getStringLength(obj: Any) : Int? {
    if (obj is String){
        return obj.length
    }
    return null
}
fun getStringLength2(obj: Any) :Int? {
    if (obj !is String){
        return null
    }
    return obj.length
}
fun getStringLength3(obj: Any) :Int? {
    if (obj is String && obj.length > 0){
        return obj.length
    }
    return null
}

fun doFor(){
    val items = listOf("apple", "banana", "car")
    for (item in items){
        println(item)
    }
}
fun doFor2(){
    val items = listOf("apple2", "banana2", "car2")
    for (itemIndex in items.indices){
        println("item at $itemIndex is ${items[itemIndex]}")
    }
}
fun doWhile(){
    val items = listOf("apple3", "banana3", "car3")
    var index = 0
    while (index < items.size){
        println("item at $index is ${items[index]}")
        index++
    }
}
fun describe(obj: Any): String =
    when(obj) {
        1 -> "One"
        "Hello" -> "Greeting"
        is Long -> "Long"
        !is String -> "Not a string"
        else -> "Unknown"
    }

fun aboutRange(){
    println("----------------------")
    val x = 10
    val y = 9
    if (x in 1..y+1){
        println("fits in range")
    }

    val list = listOf("a", "b", "c")
    if (-1 !in  0..list.lastIndex){
        println("-1 is out of range")
    }
    if (list.size !in list.indices){
        println("list size is out of valid list indices range, too")
    }

    for (x in 1..5){
        println(x)
    }

    for (x in 1..10 step 2){
        println(x)
    }

    for (x in 1..10 step 2){
        println(x)
    }
    println("==================")
    for (x in 9 downTo 0 step 3){
        println(x)
    }
}
fun aboutSet(){
    val items = setOf("apple", "banana", "car")
    for (item in items){
        println(item)
    }
    when{
        "orange" in items -> println("juicy")
        "apple" in items -> println("apple is fine too")
        "banana" in items -> println("banana is fine too")
    }
    println("==================")

    val fruits = listOf("banana", "avocado", "absorbed", "apple", "car")
    fruits.filter { it.startsWith("a") }
        .sortedBy { it }
        .map { it.toUpperCase() }
        .forEach { println(it) }
}

abstract class Shape(val sides: List<Double>) {
    val perimeter : Double get() = sides.sum()
    abstract fun calculateArea(): Double
}
interface RectangleProperties {
    val isSquare: Boolean
}
class Rectangle (var height: Double, var length: Double) : Shape(listOf(height, length, height, length)), RectangleProperties {
    override val isSquare: Boolean  get() = length == height
//    override var isSquare: Boolean

    override fun calculateArea(): Double = height * length
}

class Triangle (var sideA: Double, var sideB:Double, var sideC:Double) : Shape(listOf(sideA, sideB, sideC)) {
    override fun calculateArea(): Double {
        val s = perimeter / 2
        return Math.sqrt(s * (s - sideA) * (s - sideB) * (s - sideC))
    }
}

class TestForShape(var x: Double, var y: Double) : Shape(listOf(x, y)){
     override fun calculateArea(): Double {
        var s = x * y
        return s
    }

    fun test () : Int{
        return ((x + y) * 2).roundToInt()
    }
}